package com.powerbank.gateway.handler;

import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * 网关降级处理器
 * 处理服务不可用时的降级响应
 */
@Slf4j
@Component
public class FallbackHandler {

    /**
     * 配置降级路由
     */
    public RouterFunction<ServerResponse> fallbackRoutes() {
        return RouterFunctions.route()
                .GET("/fallback/user", this::userFallback)
                .GET("/fallback/payment", this::paymentFallback)
                .GET("/fallback/order", this::orderFallback)
                .GET("/fallback/device", this::deviceFallback)
                .GET("/fallback/finance", this::financeFallback)
                .GET("/fallback/admin", this::adminFallback)
                .build();
    }

    /**
     * 用户服务降级
     */
    public Mono<ServerResponse> userFallback(ServerRequest request) {
        log.warn("用户服务不可用，触发降级处理");
        return createFallbackResponse("用户服务暂时不可用，请稍后重试");
    }

    /**
     * 支付服务降级
     */
    public Mono<ServerResponse> paymentFallback(ServerRequest request) {
        log.warn("支付服务不可用，触发降级处理");
        return createFallbackResponse("支付服务暂时不可用，请稍后重试");
    }

    /**
     * 订单服务降级
     */
    public Mono<ServerResponse> orderFallback(ServerRequest request) {
        log.warn("订单服务不可用，触发降级处理");
        return createFallbackResponse("订单服务暂时不可用，请稍后重试");
    }

    /**
     * 设备服务降级
     */
    public Mono<ServerResponse> deviceFallback(ServerRequest request) {
        log.warn("设备服务不可用，触发降级处理");
        return createFallbackResponse("设备服务暂时不可用，请稍后重试");
    }

    /**
     * 财务服务降级
     */
    public Mono<ServerResponse> financeFallback(ServerRequest request) {
        log.warn("财务服务不可用，触发降级处理");
        return createFallbackResponse("财务服务暂时不可用，请稍后重试");
    }

    /**
     * 运营后台降级
     */
    public Mono<ServerResponse> adminFallback(ServerRequest request) {
        log.warn("运营后台不可用，触发降级处理");
        return createFallbackResponse("运营后台暂时不可用，请稍后重试");
    }

    /**
     * 创建降级响应
     */
    private Mono<ServerResponse> createFallbackResponse(String message) {
        Map<String, Object> result = new HashMap<>();
        result.put("code", 503);
        result.put("message", message);
        result.put("data", null);
        result.put("timestamp", System.currentTimeMillis());

        return ServerResponse.status(HttpStatus.SERVICE_UNAVAILABLE)
                .contentType(MediaType.APPLICATION_JSON)
                .bodyValue(result);
    }

    /**
     * 通用异常处理
     */
    public Mono<Void> handleException(ServerHttpResponse response, String message) {
        response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");

        Map<String, Object> result = new HashMap<>();
        result.put("code", 500);
        result.put("message", message);
        result.put("data", null);
        result.put("timestamp", System.currentTimeMillis());

        String body = JSONUtil.toJsonStr(result);
        DataBuffer buffer = response.bufferFactory().wrap(body.getBytes(StandardCharsets.UTF_8));
        
        return response.writeWith(Mono.just(buffer));
    }
}